package com.qiaofang.applet.service.property.service.impl;

import com.google.common.collect.Lists;
import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.common.context.QfContextHolder;
import com.qiaofang.applet.constants.PropertyTradeTypeConstants;
import com.qiaofang.applet.constants.UpDownFlagConstants;
import com.qiaofang.applet.service.property.domain.EstateHouseTypeFy;
import com.qiaofang.applet.service.property.domain.Property;
import com.qiaofang.applet.service.property.repository.EstateHouseTypeFyRepository;
import com.qiaofang.applet.service.property.service.EstateHouseTypeFyService;
import com.qiaofang.applet.service.property.service.dto.*;
import com.qiaofang.applet.service.property.service.mapstruct.EstateHouseTypeFyMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class EstateHouseTypeFyServiceImpl extends MongoBaseService<EstateHouseTypeFy, String> implements EstateHouseTypeFyService {

    private final EstateHouseTypeFyRepository repository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private EstateHouseTypeFyMapper estateHouseTypeFyMapper;


    @Autowired
    public EstateHouseTypeFyServiceImpl(EstateHouseTypeFyRepository repository) {
        super(repository);
        this.repository = repository;
    }


    /**
     * 查询户型房源集合
     *
     * @param estatePropertyQueryDto
     * @return
     */
    @Override
    public Map<String, List<EstatePropertyListDto>> getHouseTypeFyMap(EstatePropertyQueryDto estatePropertyQueryDto) {

        Query query = new Query().addCriteria(Criteria.where("estateUniqueUuid").is(estatePropertyQueryDto.getEstateUniqueUuid()));
        query.addCriteria(Criteria.where("photoUuid").is(estatePropertyQueryDto.getPhotoUuid()));
        //当前楼盘已添加所有房源propertyUniqueUuid
        List<String> propertyUniqueUuids = Optional.ofNullable(mongoTemplate.find(query, EstateHouseTypeFy.class)).orElseGet(Lists::newArrayList)
                .stream().map(EstateHouseTypeFy::getPropertyUniqueUuid).collect(Collectors.toList());
        Map<String, List<EstatePropertyListDto>> resultMap = new HashMap<>();
        //当前户型房源查询
        if (estatePropertyQueryDto.getQueryFlag() == 1) {
            Query queryAll = new Query().addCriteria(Criteria.where("propertyUniqueUuid").in(propertyUniqueUuids));
            queryAll.addCriteria(Criteria.where("upDownFlag").is(UpDownFlagConstants.UP_FLAG.getValue()));
            if (StringUtils.isNotBlank(estatePropertyQueryDto.getPropertyNo())) {
                queryAll.addCriteria(Criteria.where("propertyNo").regex(".*?" + estatePropertyQueryDto.getPropertyNo() + ".*"));
            }
            List<Property> properties = mongoTemplate.find(queryAll, Property.class);
            List<EstatePropertyListDto> estatePropertyListDtos = estateHouseTypeFyMapper.domainListToDtoList(properties);
            //出租  出售  租售
            Map<String, List<EstatePropertyListDto>> tradeTypeMap = Optional.ofNullable(estatePropertyListDtos).orElseGet(Lists::newArrayList)
                    .stream().collect(Collectors.groupingBy(EstatePropertyListDto::getTradeType));
            List<EstatePropertyListDto> rentList = new ArrayList<>();
            List<EstatePropertyListDto> saleList = new ArrayList<>();
            if (tradeTypeMap.get(PropertyTradeTypeConstants.ALL) != null) {
                rentList.addAll(tradeTypeMap.get(PropertyTradeTypeConstants.ALL));
                saleList.addAll(tradeTypeMap.get(PropertyTradeTypeConstants.ALL));
            }
            if (tradeTypeMap.get(PropertyTradeTypeConstants.RENT) != null) {
                rentList.addAll(tradeTypeMap.get(PropertyTradeTypeConstants.RENT));
            }
            if (tradeTypeMap.get(PropertyTradeTypeConstants.SALE) != null) {
                saleList.addAll(tradeTypeMap.get(PropertyTradeTypeConstants.SALE));
            }
            resultMap.put("rent", rentList);
            resultMap.put("sale", saleList);
            return resultMap;
        } else {
            Query queryAll = new Query();
            Criteria criteria = new Criteria();
            criteria.and("upDownFlag").is(UpDownFlagConstants.UP_FLAG.getValue());
            criteria.and("estateUniqueUuid").is(estatePropertyQueryDto.getEstateUniqueUuid());
            criteria.and("propertyUniqueUuid").nin(propertyUniqueUuids);
            if (StringUtils.isNotBlank(estatePropertyQueryDto.getPropertyNo())) {
                criteria.and("propertyNo").regex(".*?" + estatePropertyQueryDto.getPropertyNo() + ".*");
            }
            if (estatePropertyQueryDto.getCountF() != 0) {
                criteria.and("countF").is(estatePropertyQueryDto.getCountF());
            }
            if (estatePropertyQueryDto.getCountT() != 0) {
                criteria.and("countT").is(estatePropertyQueryDto.getCountT());
            }
            if (estatePropertyQueryDto.getCountW() != 0) {
                criteria.and("countW").is(estatePropertyQueryDto.getCountW());
            }
            criteria.orOperator(Criteria.where("tradeType").is(estatePropertyQueryDto.getQueryFlag() == 2 ? PropertyTradeTypeConstants.SALE : PropertyTradeTypeConstants.RENT), Criteria.where("tradeType").is(PropertyTradeTypeConstants.ALL));
            queryAll.addCriteria(criteria);
            List<Property> properties = mongoTemplate.find(queryAll, Property.class);
            List<EstatePropertyListDto> estatePropertyListDtos = estateHouseTypeFyMapper.domainListToDtoList(properties);
            resultMap.put("general", estatePropertyListDtos);
        }
        return resultMap;
    }

    /**
     * 添加户型房源
     *
     * @param estatePropertyAddDto
     */
    @Override
    public void addHouseTypeFy(EstatePropertyAddDto estatePropertyAddDto) {
        String estateUniqueUuid = estatePropertyAddDto.getEstateUniqueUuid();
        String photoUuid = estatePropertyAddDto.getPhotoUuid();
        Set<String> propertyUniqueUuidSet = estatePropertyAddDto.getPropertyUniqueUuidSet();
        if (!CollectionUtils.isEmpty(propertyUniqueUuidSet)) {
            List<EstateHouseTypeFy> list = new ArrayList<>(propertyUniqueUuidSet.size());
            for (String propertyUniqueUuid : propertyUniqueUuidSet) {
                EstateHouseTypeFy houseTypeFy = repository.findByEstateUniqueUuidAndPhotoUuidAndPropertyUniqueUuid(estateUniqueUuid, photoUuid, propertyUniqueUuid);
                if (houseTypeFy != null) {
                    continue;
                }
                houseTypeFy = new EstateHouseTypeFy();
                houseTypeFy.setEstateUniqueUuid(estateUniqueUuid);
                houseTypeFy.setPhotoUuid(photoUuid);
                houseTypeFy.setPropertyUniqueUuid(propertyUniqueUuid);
                list.add(houseTypeFy);
            }
            if (!CollectionUtils.isEmpty(list)) {
                repository.saveAll(list);
            }
        }
    }

    /**
     * 移除户型房源关联关系
     *
     * @param estatePropertyRemoveDto
     */
    @Override
    public void deleteHouseTypeFy(EstatePropertyRemoveDto estatePropertyRemoveDto) {
        String estateUniqueUuid = estatePropertyRemoveDto.getEstateUniqueUuid();
        String photoUuid = estatePropertyRemoveDto.getPhotoUuid();
        String propertyUniqueUuid = estatePropertyRemoveDto.getPropertyUniqueUuid();
        repository.deleteByEstateUniqueUuidAndPhotoUuidAndPropertyUniqueUuid(estateUniqueUuid, photoUuid, propertyUniqueUuid);
    }

    @Override
    public EstateHouseTypeCountDto getHouseTypeCount(String estateUniqueUuid, String photoUuid) {
        EstateHouseTypeCountDto estateHouseTypeCountDto = new EstateHouseTypeCountDto();
        int saleNum = 0;
        int rentNum = 0;
        List<EstateHouseTypeFy> fyList = repository.findByEstateUniqueUuidAndPhotoUuid(estateUniqueUuid, photoUuid);
        if (!CollectionUtils.isEmpty(fyList)) {
            List<String> propertyUniqueUuids = Optional.ofNullable(fyList).orElseGet(Lists::newArrayList)
                    .stream().map(EstateHouseTypeFy::getPropertyUniqueUuid).collect(Collectors.toList());
            Query query = new Query();
            Criteria criteria = Criteria.where("upDownFlag").is(UpDownFlagConstants.UP_FLAG.getValue());
            criteria.and("propertyUniqueUuid").in(propertyUniqueUuids);
            query.addCriteria(criteria);
            Map<String, List<Property>> propertyMap = Optional.ofNullable(mongoTemplate.find(query, Property.class)).orElseGet(Lists::newArrayList)
                    .stream().collect(Collectors.groupingBy(Property::getTradeType));

            if (!CollectionUtils.isEmpty(propertyMap.get(PropertyTradeTypeConstants.ALL))) {
                saleNum += propertyMap.get(PropertyTradeTypeConstants.ALL).size();
                rentNum += propertyMap.get(PropertyTradeTypeConstants.ALL).size();
            }
            if (!CollectionUtils.isEmpty(propertyMap.get(PropertyTradeTypeConstants.RENT))) {
                rentNum += propertyMap.get(PropertyTradeTypeConstants.RENT).size();
            }
            if (!CollectionUtils.isEmpty(propertyMap.get(PropertyTradeTypeConstants.SALE))) {
                saleNum += propertyMap.get(PropertyTradeTypeConstants.SALE).size();
            }
        }
        estateHouseTypeCountDto.setSaleNum(saleNum);
        estateHouseTypeCountDto.setRentNum(rentNum);
        return estateHouseTypeCountDto;
    }
}
